package com.generator;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.TopLevelClass;

import java.io.BufferedWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ServicePlugin extends PluginAdapter{

	String packageInfo="com.glp.web";
	
	String pagingInfo = packageInfo+".page.params";
	String paramsValidate = packageInfo+".page.annotation";
	
	String servicePackage=packageInfo+".generator.service";
	String serviceImplPackage=packageInfo+".generator.service.impl";
	String entityPackage=packageInfo+".generator.entity";
	String mappingPackage=packageInfo+".generator.mapper";
	String jsonPackage=packageInfo+".generator.web.json";

	public static String rootDir="D:\\project\\HD\\glp\\src\\main\\";

	public static String serviceRootDir=rootDir+"java\\";
	
	Configuration cfg;
	public ServicePlugin() {
		super();
		cfg = new Configuration(Configuration.VERSION_2_3_22);
		cfg.setClassForTemplateLoading(this.getClass(),"/FreeMarker");
		cfg.setDefaultEncoding("UTF-8");
		cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
	}

	@Override
	public boolean validate(List<String> warnings) {
		return true;
	}

	@Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
    	String domainObjectName=introspectedTable.getFullyQualifiedTable().getDomainObjectName();
    	List<IntrospectedColumn> columns = introspectedTable.getPrimaryKeyColumns();
    	
		try {
			Map<String, String> prop = new HashMap<>();
			prop.put("domainObjectName", domainObjectName);
			prop.put("lowerDomainObjectName", StrUtil.lowerFirst(domainObjectName));
			int pkType = 0;
			if(columns.size() == 1) {
				prop.put("pk", StrUtil.upperFirst(columns.get(0).getJavaProperty()));
	    	}else if(columns.size() == 2 && introspectedTable.getAllColumns().size() == 2){
				pkType = 1;
				prop.put("pk", "pk");
	    	}else {
				pkType = 3;
	    	    prop.put("pk", "pk");
	    	}
			prop.put("pagingInfo", pagingInfo);
			prop.put("servicePackage", servicePackage);
			prop.put("serviceImplPackage", serviceImplPackage);
			prop.put("entityPackage", entityPackage);
			prop.put("mappingPackage", mappingPackage);
			prop.put("jsonPackage", jsonPackage);
			prop.put("paramsValidate", paramsValidate);

			Template temp = null;
			if(pkType == 1) {
			    temp = cfg.getTemplate("service/RelationshipService.java");
			}else if(pkType == 0){
			    temp = cfg.getTemplate("service/Service.java");
			}else{
				temp = cfg.getTemplate("service/CompositivePrimaryKeyService.java");
			}
			BufferedWriter outputStream = FileUtil.getWriter(StrUtil.format("{}/{}/{}Service.java", serviceRootDir,servicePackage.replaceAll("\\.", "/"),domainObjectName),Charset.forName("UTF-8"),false);
			temp.process(prop, outputStream);
			outputStream.close();
			if(pkType == 1) {
				temp = cfg.getTemplate("service/impl/RelationshipServiceImpl.java");
			}else if(pkType == 0){
				temp = cfg.getTemplate("service/impl/ServiceImpl.java");
			}else{
				temp = cfg.getTemplate("service/impl/CompositivePrimaryKeyServiceImpl.java");
			}
			outputStream = FileUtil.getWriter(StrUtil.format("{}/{}/{}ServiceImpl.java", serviceRootDir, serviceImplPackage.replaceAll("\\.", "/"),domainObjectName),Charset.forName("UTF-8"),false);
			temp.process(prop, outputStream);
			outputStream.close();

			if(pkType == 1) {
				temp = cfg.getTemplate("web/json/RelationshipJson.java");
			}else if(pkType == 0){
				temp = cfg.getTemplate("web/json/Json.java");
			}else{
				temp = cfg.getTemplate("web/json/CompositivePrimaryKeyJson.java");
			}
			outputStream = FileUtil.getWriter(StrUtil.format("{}/{}/{}Json.java", serviceRootDir, jsonPackage.replaceAll("\\.", "/"),domainObjectName),Charset.forName("UTF-8"),false);
			temp.process(prop, outputStream);
			outputStream.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		List<GeneratedJavaFile> mapperJavaFiles = new ArrayList<GeneratedJavaFile>();
        return mapperJavaFiles;
    }
	@Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass,
            IntrospectedTable introspectedTable) {
        generateService(introspectedTable, topLevelClass);
        return true;
    }

    @Override
    public boolean modelRecordWithBLOBsClassGenerated(
            TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
    	generateService(introspectedTable, topLevelClass);
        return true;
    }

    @Override
    public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass,
            IntrospectedTable introspectedTable) {
    	generateService(introspectedTable, topLevelClass);
        return true;
    }
    private void generateService(IntrospectedTable introspectedTable,
            TopLevelClass topLevelClass) {
    	
    }
}
